Skip to content

doc(demos): enhance assistant demo#295

Open
gene9831 wants to merge 1 commit intoopentiny:developfrom
gene9831:docs/assistant-demo
Open

doc(demos): enhance assistant demo#295
gene9831 wants to merge 1 commit intoopentiny:developfrom
gene9831:docs/assistant-demo

Conversation

@gene9831
Copy link
Collaborator

@gene9831 gene9831 commented Jan 30, 2026

  • Introduced new utility files: assistantConstants.ts, mockMcp.ts, and responseProvider.ts to support enhanced functionality in the assistant demo.
  • Updated Assistant.vue to utilize the new response provider and mock MCP tool, improving the interaction flow.
  • Revised documentation in assistant.md to reflect the inclusion of new demo files, ensuring comprehensive examples for users.
  • Updated sidebar items in theme configuration for better navigation and clarity on tool usage.

Summary by CodeRabbit

  • Documentation

    • Reorganized sidebar navigation in tools section with renamed items (useMessage, useConversation, AIClient) for improved clarity.
    • Updated documentation titles for better consistency across tool guides.
  • New Features

    • Added Model Context Protocol (MCP) tool integration support to the assistant demo with mock tool execution capabilities.
    • Enhanced assistant response handling with plugin-based architecture for more flexible tool integration.

✏️ Tip: You can customize this high-level summary in your review settings.

…CP integration

- Introduced new utility files: `assistantConstants.ts`, `mockMcp.ts`, and `responseProvider.ts` to support enhanced functionality in the assistant demo.
- Updated `Assistant.vue` to utilize the new response provider and mock MCP tool, improving the interaction flow.
- Revised documentation in `assistant.md` to reflect the inclusion of new demo files, ensuring comprehensive examples for users.
- Updated sidebar items in theme configuration for better navigation and clarity on tool usage.
@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

Walkthrough

The PR refactors the Assistant demo component to use a provider-based architecture with MCP (Model Context Protocol) tool integration, introduces comprehensive constants and configuration modules for UI data, and updates documentation headers for consistency.

Changes

Cohort / File(s) Summary
Documentation Headers
docs/src/tools/ai-client.md, docs/src/tools/conversation.md, docs/src/tools/message.md
Titles reordered for consistency; no functional changes to documentation content.
Assistant Constants & Configuration
docs/demos/examples/assistantConstants.ts, docs/demos/examples/mockMcp.ts
New modules introducing UI constants (prompts, pills, overlays), type definitions (PromptItemData, PillConfig), comprehensive template suggestions catalog, and mock MCP tooling interface with trigger detection and tool call simulation.
Response Provider Integration
docs/demos/examples/responseProvider.ts
New provider module implementing assistantResponseProvider that branches between real API streaming and mock MCP flow based on trigger keywords; includes mockMcpStream generator for simulated tool-calling behavior.
Assistant Component Refactoring
docs/demos/examples/Assistant.vue, docs/.vitepress/themeConfig.ts
Major refactor replacing SSE streaming with provider-based flow; replaces sseStreamToGenerator with toolPlugin and useConversation; extracts hard-coded UI data (promptItems, popover, menu items) to constants-driven generation; adds MCP tool support via plugins. Sidebar config reorders tool items.
Demo Manifest Update
docs/src/examples/assistant.md
Demo tag expanded to load responseProvider, assistantConstants, and mockMcp modules alongside Assistant.vue.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Assistant as Assistant Component
    participant Provider as Response Provider
    participant API as /api/chat/completions
    participant MockMCP as Mock MCP Stream
    participant Tools as MCP Tools

    User->>Assistant: Submit message with content
    Assistant->>Provider: assistantResponseProvider(requestBody, abortSignal)
    
    Provider->>Provider: Check for MCP trigger keywords
    alt MCP Keywords Detected or Last Message is Tool
        Provider->>MockMCP: mockMcpStream(requestBody, abortSignal)
        MockMCP->>MockMCP: Extract search query from message
        MockMCP->>Tools: Analyze for mcp_search tool call
        Tools-->>MockMCP: tool_calls delta with extracted query
        MockMCP-->>Provider: Yield tool_calls delta
        
        MockMCP->>MockMCP: Generate assistant summary response
        MockMCP-->>Provider: Yield assistant content with mock results
    else Standard Chat Flow
        Provider->>API: POST /api/chat/completions (streaming enabled)
        API-->>Provider: SSE stream of chat completion
        Provider->>Provider: Convert SSE to AsyncGenerator
    end
    
    Provider-->>Assistant: AsyncGenerator<ChatCompletion>
    Assistant->>Assistant: Process deltas via toolPlugin
    Assistant-->>User: Display response with formatted content
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 The rabbit hops through code with glee,
Provider patterns, tools set free!
MCP flows dance, mocks take the stage,
Constants extracted page by page.
Where once was SSE's streaming call,
Plugin-driven architecture conquers all! 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'doc(demos): enhance assistant demo' accurately reflects the main changes—adding and improving assistant demo files and configuration.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 30, 2026

✅ Preview build completed successfully!

Click the image above to preview.
Preview will be automatically removed when this PR is closed.

@github-actions
Copy link
Contributor

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/demos/examples/Assistant.vue (1)

193-214: ⚠️ Potential issue | 🟠 Major

Guard JSON.parse in tool handler to prevent conversation failures on invalid tool arguments.

The || '{}' fallback only protects against undefined or null, not against malformed JSON strings. If the LLM generates invalid JSON in toolCall.function.arguments, JSON.parse will throw an unhandled exception and break the conversation.

Suggested fix
       toolPlugin({
         getTools: async () => MCP_TOOLS,
         callTool: async (toolCall) => {
-          const args = JSON.parse(toolCall.function?.arguments || '{}')
-          return callMcpTool(toolCall.function?.name || '', args)
+          let args: Record<string, unknown> = {}
+          try {
+            args = JSON.parse(toolCall.function?.arguments || '{}')
+          } catch {
+            // keep empty args on parse failure
+          }
+          return callMcpTool(toolCall.function?.name || '', args)
         },
       }),
🤖 Fix all issues with AI agents
In `@docs/demos/examples/assistantConstants.ts`:
- Around line 265-268: getContainerStyles currently accesses
window.self/window.top which will crash during SSR; guard access by checking
typeof window !== "undefined" (and optionally typeof window.self !==
"undefined") before using window.self/window.top and return a safe default for
SSR. Update the getContainerStyles function to perform the typeof window check
first, then use the existing self/top logic when available; ensure the function
still returns the same objects ({ height: '100vh' } or { top: '112px', height:
'calc(100vh - 112px)' }) in the appropriate branches.

In `@docs/demos/examples/responseProvider.ts`:
- Around line 83-116: After the 300ms artificial delay and before emitting the
tool_calls yield, check the request abort signal and stop early if aborted:
after the await new Promise((r) => setTimeout(r, 300)) add a guard like if
(signal?.aborted) return (or throw new DOMException('Aborted', 'AbortError')),
so the code that constructs and yields the tool_calls object (which uses id,
query, extractSearchQuery, userContent) does not run when the request was
cancelled; also ensure any timers/listeners used by that Promise are cleaned up
if you wire the signal to clearTimeout.

Comment on lines +265 to +268
// --- Container styles ---
export function getContainerStyles(): Record<string, string> {
return window.self !== window.top ? { height: '100vh' } : { top: '112px', height: 'calc(100vh - 112px)' }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard window access to avoid SSR crashes.
If this runs during VitePress SSR, window is undefined and will throw. Add a guard so the docs build doesn’t break.

🔧 Proposed fix
 export function getContainerStyles(): Record<string, string> {
-  return window.self !== window.top ? { height: '100vh' } : { top: '112px', height: 'calc(100vh - 112px)' }
+  if (typeof window === 'undefined') {
+    return {}
+  }
+  return window.self !== window.top ? { height: '100vh' } : { top: '112px', height: 'calc(100vh - 112px)' }
 }
🤖 Prompt for AI Agents
In `@docs/demos/examples/assistantConstants.ts` around lines 265 - 268,
getContainerStyles currently accesses window.self/window.top which will crash
during SSR; guard access by checking typeof window !== "undefined" (and
optionally typeof window.self !== "undefined") before using
window.self/window.top and return a safe default for SSR. Update the
getContainerStyles function to perform the typeof window check first, then use
the existing self/top logic when available; ensure the function still returns
the same objects ({ height: '100vh' } or { top: '112px', height: 'calc(100vh -
112px)' }) in the appropriate branches.

Comment on lines +83 to +116
// First round: user message contains keyword -> return tool_calls
const userContent = typeof last?.content === 'string' ? last.content : ''
const query = extractSearchQuery(userContent)
await new Promise((r) => setTimeout(r, 300))
yield {
id,
object: 'chat.completion.chunk',
created: Math.floor(Date.now() / 1000),
model: 'mock-mcp',
system_fingerprint: null,
choices: [
{
index: 0,
message: undefined,
delta: {
role: 'assistant',
tool_calls: [
{
index: 0,
id: 'call_mcp_search_' + Date.now(),
type: 'function',
function: {
name: 'mcp_search',
arguments: JSON.stringify({ query }),
},
},
],
},
finish_reason: 'tool_calls',
logprobs: null,
},
],
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Respect abort before emitting tool_calls.

If the request is aborted during the 300ms delay, the tool call is still emitted. Add an abort check before yielding.

🛠️ Proposed fix
   await new Promise((r) => setTimeout(r, 300))
+  if (abortSignal.aborted) return
   yield {
     id,
     object: 'chat.completion.chunk',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// First round: user message contains keyword -> return tool_calls
const userContent = typeof last?.content === 'string' ? last.content : ''
const query = extractSearchQuery(userContent)
await new Promise((r) => setTimeout(r, 300))
yield {
id,
object: 'chat.completion.chunk',
created: Math.floor(Date.now() / 1000),
model: 'mock-mcp',
system_fingerprint: null,
choices: [
{
index: 0,
message: undefined,
delta: {
role: 'assistant',
tool_calls: [
{
index: 0,
id: 'call_mcp_search_' + Date.now(),
type: 'function',
function: {
name: 'mcp_search',
arguments: JSON.stringify({ query }),
},
},
],
},
finish_reason: 'tool_calls',
logprobs: null,
},
],
}
}
// First round: user message contains keyword -> return tool_calls
const userContent = typeof last?.content === 'string' ? last.content : ''
const query = extractSearchQuery(userContent)
await new Promise((r) => setTimeout(r, 300))
if (abortSignal.aborted) return
yield {
id,
object: 'chat.completion.chunk',
created: Math.floor(Date.now() / 1000),
model: 'mock-mcp',
system_fingerprint: null,
choices: [
{
index: 0,
message: undefined,
delta: {
role: 'assistant',
tool_calls: [
{
index: 0,
id: 'call_mcp_search_' + Date.now(),
type: 'function',
function: {
name: 'mcp_search',
arguments: JSON.stringify({ query }),
},
},
],
},
finish_reason: 'tool_calls',
logprobs: null,
},
],
}
}
🤖 Prompt for AI Agents
In `@docs/demos/examples/responseProvider.ts` around lines 83 - 116, After the
300ms artificial delay and before emitting the tool_calls yield, check the
request abort signal and stop early if aborted: after the await new Promise((r)
=> setTimeout(r, 300)) add a guard like if (signal?.aborted) return (or throw
new DOMException('Aborted', 'AbortError')), so the code that constructs and
yields the tool_calls object (which uses id, query, extractSearchQuery,
userContent) does not run when the request was cancelled; also ensure any
timers/listeners used by that Promise are cleaned up if you wire the signal to
clearTimeout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant